package com.ezops.poc.validations.validators;

import java.lang.reflect.Field;

import com.ezops.poc.validations.result.FieldValidationError;
import com.ezops.poc.validations.result.ValidationResult;

/**
 * Checks if the field being passed lies in the specified range.
 * 
 * @author vgaurav
 * 
 */
public class RangeValidator implements IValidators {

	private String fieldName, minValue, maxValue;
	private RangeType type = RangeType.NONE;

	enum RangeType {
		LESS_THAN, GREATER_THAN, BETWEEN, NONE;
	}

	public RangeValidator() {
	}

	@Override
	public void init(String fieldName, String... param) {
		if (param == null || param.length == 0) {
			return;
		}
		this.fieldName = fieldName;

		String[] values = param[0].trim().split("");

		// value[0] would be ""
		if (">".equals(values[1])) {
			this.type = RangeType.GREATER_THAN;
			this.minValue = values[2];
		} else if ("<".equals(values[1])) {
			this.type = RangeType.LESS_THAN;
			this.maxValue = values[2];
		} else {
			if (param[0].contains("-")) {
				values = param[0].split("-");
				this.minValue = values[0];
				this.maxValue = values[1];
			} else {

				throw new IllegalArgumentException(
						"Range validation shoud either be > or < or between like x-y");
			}
		}
	}

	@Override
	public ValidationResult validate(Object model) {
		if (model == null) {
			throw new IllegalArgumentException("Can't not validate null model");
		}
		if (this.type.equals(RangeType.NONE)) {
			return ValidationResult.getValidResponse();
		}
		final Integer value;

		try {
			final Field field = model.getClass().getDeclaredField(fieldName);
			field.setAccessible(true);
			value = Integer.parseInt((String)field.get(model));
			switch (this.type) {
			case LESS_THAN:
				if (value < Integer.parseInt(maxValue)) {
					return ValidationResult.getValidResponse();
				}
				break;
			case GREATER_THAN:
				if (value.intValue() > Integer.parseInt(minValue)) {
					return ValidationResult.getValidResponse();
				}
				break;
			case BETWEEN:
				if (value.intValue() > Integer.parseInt(minValue)
						&& value < Integer.parseInt(maxValue)) {
					return ValidationResult.getValidResponse();
				}
			}

		} catch (Exception ex) {

		}
		return ValidationResult.getErrorResponse(new FieldValidationError() {

			public String getFieldName() {
				return fieldName;
			}

			public String getErrorMessage() {
				return "The field name " + fieldName
						+ " is not in correct range.";
			}
		});
	}

}
